/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package argtrust.argsys;

import argtrust.measure.Measure;
import argtrust.measure.IMeasureOperators;
import argtrust.trustnet.Agent;
import java.util.Map;
import java.util.LinkedHashMap;

import argtrust.logic.InferenceNode;
import argtrust.logic.FactInferenceNode;
import argtrust.logic.RuleInferenceNode;

import argtrust.belief.ITrustBeliefSemantics;
import argtrust.belief.IndirectBelief;
import argtrust.util.Pair;

/**
 *
 * @author Yuqing Tang
 */
public class MinBeliefArgument implements IBeliefArgumentSemantics {

    ITrustBeliefSemantics mTrustBelief;
    Map<Pair<Agent, Argument>, Measure> mArgumentBeliefTable = new LinkedHashMap<Pair<Agent, Argument>, Measure>();
    IMeasureOperators mBeliefOperators;

    public MinBeliefArgument(ITrustBeliefSemantics trust_belief) {
        mTrustBelief = trust_belief;
        mBeliefOperators = trust_belief.getOperators();
    }

    public IMeasureOperators getOperators() {
        return mBeliefOperators;
    }

    Measure believe_(Agent agent, InferenceNode inf_node) {
        if (inf_node instanceof FactInferenceNode) {
            FactInferenceNode fact_node = (FactInferenceNode) inf_node;
            return mTrustBelief.believe(agent, fact_node.getFactIterator().get());
        } else {
            RuleInferenceNode rule_node = (RuleInferenceNode) inf_node;
            Measure res = mTrustBelief.believe(agent, rule_node.getRuleIterator().get());
            for (InferenceNode node : rule_node.getChildrenList()) {
                Measure child_belief = believe_(agent, node);
                if (mBeliefOperators.lt(
                        child_belief.getOpMeasure(),
                        res.getOpMeasure())) {
                    res = child_belief;
                }
            }
            return res;
        }

    }

    public Measure believe(Agent agent, Argument argument) {
        Pair<Agent, Argument> key = new Pair<Agent, Argument>(agent, argument);
        Measure res = mArgumentBeliefTable.get(key);
        if (res == null) {
            res = new IndirectBelief(
                    believe_(agent, argument.getEndInferenceNode())
                    );
            mArgumentBeliefTable.put(key, res);
        }

        return res;

    }
//    public boolean isEffective(Agent agent, Defeat defeat) {
//        return !(believe(agent, defeat.getDefeatee()).getLevel()
//                > believe(agent, defeat.getDefeater()).getLevel());
//    }
}
